﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Login.OSIRISService;
using Login.Models;

namespace Login.Controllers
{
    /// <summary>
    /// The StudentController is used by SLB'ers and gives the teachers 
    /// the opportunity to manage the permission of their students.
    /// </summary>
    public class StudentController : Controller
    {
        /// <summary>
        /// Called when the user requests the Index action using GET.
        /// </summary>
        /// <returns>The view or a redirect</returns>
        [Authorize(Roles="Teacher")]
        public ActionResult Index()
        {
            /* build entry list */
            List<StudentEntry> entries = this.BuildEntries();

            /* sort the entries by name */
            entries.Sort((a, b) => a.Name.CompareTo(b.Name));

            /* create model for form */
            StudentModel model = new StudentModel();
            model.Entries = entries;

            /* return the view */
            return View(model);
        }

        /// <summary>
        /// Called when the user submits the form using POST.
        /// </summary>
        /// <param name="model">The model that was submitted</param>
        /// <returns>The view</returns>
        [Authorize(Roles="Teacher")]
        [HttpPost]
        public ActionResult Index(StudentModel model)
        {
            /* if the model is valid */
            if (ModelState.IsValid)
            {
                /* connect to the database */
                AfstudeerregistratieDataContext database = new AfstudeerregistratieDataContext();

                /* loop over entries */
                foreach (StudentEntry entry in model.Entries)
                {
                    /* find the student in the database */
                    IEnumerable<Student> students =
                        from dbStudent in database.Students
                        where dbStudent.Number == entry.Number
                        select dbStudent;

                    /* if a student was found */
                    if (students.Count() > 0)
                    {
                        /* fetch the student */
                        Student student = students.First();

                        /* modify the student */
                        student.HasPermissionOSIRIS = entry.HasPermissionOSIRIS;
                        student.HasPermissionSLB = entry.HasPermissionSLB;
                    }
                }

                /* save changes */
                database.SubmitChanges();

                /* close connection to database */
                database.Connection.Close();

                /* set flag in the viewbag */
                ViewBag.Saved = true;
            }

            /* return the view */
            return View(model);
        }

        /// <summary>
        /// Called when the teacher requests the Details action
        /// using GET.
        /// </summary>
        /// <param name="number">The number of the student</param>
        /// <returns>The view, redirect to index action</returns>
        [Authorize(Roles="Teacher")]
        [HttpGet]
        public ActionResult Detail(string number)
        {
            /* get TeacherDetails from session */
            TeacherDetails teacher = Session["Details"] as TeacherDetails;

            /* if the number is empty */
            if (number == null || number.Length == 0)
            {
                /* redirect to Index action */
                return RedirectToAction("Index");
            }

            /* connect to OSIRIS */
            OSIRISServiceClient osiris = new OSIRISServiceClient();

            /* fetch details of student */
            StudentDetails student = osiris.GetStudentDetails(number);

            /* if the student doesn't exist or this teacher is not the SLB'er */
            if (student.Number.Length == 0 || student.Slb.Number != teacher.Number)
            {
                /* redirect to Index */
                return RedirectToAction("Index");
            }

            /* set de student in the ViewBag */
            ViewBag.Student = student;

            /* return the view */
            return View();
        }

        /// <summary>
        /// Build a list of entries that are used in the form.
        /// </summary>
        /// <returns>A List object filled with StudentEntry objects</returns>
        [Authorize(Roles="Teacher")]
        private List<StudentEntry> BuildEntries()
        {
            /* get TeacherDetails from session */
            TeacherDetails docent = Session["Details"] as TeacherDetails;

            /* define List of StudentEntries */
            List<StudentEntry> entries = new List<StudentEntry>();

            /* connect to the database */
            AfstudeerregistratieDataContext database = new AfstudeerregistratieDataContext();

            /* loop over students */
            foreach (StudentDetails student in docent.Students)
            {
                /* create new entry */
                StudentEntry entry = new StudentEntry();

                /* find student in database */
                IEnumerable<Student> studentQuery =
                    from dbStudent in database.Students
                    where dbStudent.Number == student.Number
                    select dbStudent;

                /* if a student was found */
                if (studentQuery.Count() > 0)
                {
                    /* get student from query */
                    Student dbStudent = studentQuery.First();

                    /* fill entry */
                    entry.Name = dbStudent.FirstName + (dbStudent.Prefix != null ? " " + dbStudent.Prefix : "") + " " + dbStudent.LastName;
                    entry.Number = dbStudent.Number;
                    entry.HasPermissionOSIRIS = dbStudent.HasPermissionOSIRIS;
                    entry.HasPermissionSLB = dbStudent.HasPermissionSLB;
                    entry.Points = 0;

                    /* loop over results of student */
                    foreach (ResultDetails resultaat in student.Results)
                    {
                        /* add the number of points */
                        entry.Points += resultaat.Points;
                    }

                    /* add entry */
                    entries.Add(entry);
                }
                else
                {
                    /* create new Student */
                    Student newStudent = new Student();
                    newStudent.Number = student.Number;
                    newStudent.FirstName = student.FirstName;
                    newStudent.Prefix = student.Prefix;
                    newStudent.LastName = student.LastName;
                    newStudent.Email = student.Email;
                    newStudent.TelephoneNumber = student.TelephoneNumber;
                    newStudent.HasLoggedIn = false;
                    newStudent.HasPermissionSLB = false;

                    /* connect to OSIRIS */
                    OSIRISServiceClient osiris = new OSIRISServiceClient();

                    /* fetch details from OSIRIS */
                    newStudent.HasPermissionOSIRIS = osiris.AskForPermission(newStudent.Number);

                    /* close connection to OSIRIS */
                    osiris.Close();

                    /* save new Student */
                    database.Students.InsertOnSubmit(newStudent);
                    database.SubmitChanges();

                    /* fill entry */
                    entry.Name = newStudent.FirstName + (newStudent.Prefix != null ? " " + newStudent.Prefix : "") + " " + newStudent.LastName;
                    entry.Number = newStudent.Number;
                    entry.HasPermissionOSIRIS = newStudent.HasPermissionOSIRIS;
                    entry.HasPermissionSLB = newStudent.HasPermissionSLB;
                    entry.Points = 0;

                    /* loop over results of student */
                    foreach (ResultDetails result in student.Results)
                    {
                        /* add the number of points */
                        entry.Points += result.Points;
                    }

                    /* add entry */
                    entries.Add(entry);
                }
            }

            /* close database connection */
            database.Connection.Close();

            /* return the entries */
            return entries;
        }
    }
}
